<template>
  <div class="ppt-container">
    <div class="page-header">
      <h1>PPT主题生成</h1>
      <p>智能生成教学PPT主题和大纲</p>
    </div>

    <div class="content-wrapper">
      <!-- 左侧输入表单 -->
      <div class="left-panel">
        <div class="form-card">
          <h3>PPT生成参数</h3>
          <form @submit.prevent="generatePPT">
            <div class="form-group">
              <label>课程主题</label>
              <input 
                v-model="form.topic" 
                type="text" 
                placeholder="请输入课程主题，如：人工智能基础"
                required
              >
            </div>
            
            <div class="form-group">
              <label>学科</label>
              <select v-model="form.subject" required>
                <option value="">请选择学科</option>
                <option value="数学">数学</option>
                <option value="语文">语文</option>
                <option value="英语">英语</option>
                <option value="物理">物理</option>
                <option value="化学">化学</option>
                <option value="生物">生物</option>
                <option value="历史">历史</option>
                <option value="地理">地理</option>
                <option value="政治">政治</option>
                <option value="信息技术">信息技术</option>
                <option value="其他">其他</option>
              </select>
            </div>
            
            <div class="form-group">
              <label>年级</label>
              <select v-model="form.grade" required>
                <option value="">请选择年级</option>
                <option value="小学低年级">小学低年级</option>
                <option value="小学中年级">小学中年级</option>
                <option value="小学高年级">小学高年级</option>
                <option value="初中">初中</option>
                <option value="高中">高中</option>
                <option value="大学">大学</option>
              </select>
            </div>
            
            <div class="form-group">
              <label>PPT页数</label>
              <select v-model="form.slideCount" required>
                <option value="">请选择页数</option>
                <option value="10-15">10-15页</option>
                <option value="15-20">15-20页</option>
                <option value="20-25">20-25页</option>
                <option value="25-30">25-30页</option>
              </select>
            </div>
            
            <div class="form-group">
              <label>教学重点</label>
              <textarea 
                v-model="form.keyPoints" 
                placeholder="请输入本课程的教学重点和难点"
                rows="3"
              ></textarea>
            </div>
            
            <button type="submit" class="generate-btn" :disabled="loading">
              <span v-if="loading">生成中...</span>
              <span v-else>生成PPT主题</span>
            </button>
          </form>
        </div>
      </div>

      <!-- 右侧智能体返回结果 -->
      <div class="right-panel">
        <div class="agent-output-card">
          <div class="output-header">
            <h3><i class="icon-robot"></i>智能体返回结果</h3>
            <div class="status-indicator" :class="{ 'loading': loading, 'success': pptResult, 'error': errorMessage }">
              <span v-if="loading">生成中...</span>
              <span v-else-if="pptResult">生成完成</span>
              <span v-else-if="errorMessage">生成失败</span>
              <span v-else>等待生成</span>
            </div>
          </div>
          
          <!-- 加载状态 -->
          <div v-if="loading" class="loading-state">
            <div class="loading-spinner"></div>
            <p>智能体正在生成PPT内容，请稍候...</p>
          </div>
          
          <!-- 成功状态 -->
          <div v-else-if="pptResult" class="success-state">
            <div class="result-content">
              <div 
                class="content-display" 
                v-html="formattedPptContent"
                @click="handleLinkClick"
              ></div>
            </div>
            
            <div class="action-buttons">
              <button v-if="hasDownloadLink" @click="downloadPPT" class="download-btn primary">
                <i class="icon-download"></i>
                下载PPT文件
              </button>
              <button @click="copyResult" class="copy-btn">
                <i class="icon-copy"></i>复制内容
              </button>
              <button @click="downloadResult" class="download-btn">
                <i class="icon-download"></i>下载文本
              </button>
            </div>
          </div>
          
          <!-- 错误状态 -->
          <div v-else-if="errorMessage" class="error-state">
            <div class="error-icon">
              <i class="icon-warning"></i>
            </div>
            <h4>生成失败</h4>
            <p>{{ errorMessage }}</p>
            <button @click="retryGeneration" class="retry-btn">重新生成</button>
          </div>
          
          <!-- 初始状态 -->
          <div v-else class="initial-state">
            <div class="placeholder-icon">
              <i class="icon-document"></i>
            </div>
            <h4>等待生成PPT内容</h4>
            <p>请在左侧填写PPT生成参数，然后点击生成按钮</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'
import apiService from '../../api'
import axios from 'axios'

// 表单数据
const form = reactive({
  topic: '',
  subject: '',
  grade: '',
  slideCount: '',
  keyPoints: ''
})

// 状态管理
const loading = ref(false)
const pptResult = ref('')
const errorMessage = ref('')
const downloadUrl = ref('')
const hasDownloadLink = ref(false)
const linkStatus = ref('pending') // 'ready' | 'pending'
const statusMessage = ref('')

// 计算属性：格式化PPT内容
const formattedPptContent = computed(() => {
  if (!pptResult.value) return ''
  
  // OSS PPT链接正则表达式
  const ossPptRegex = /https:\/\/pptself-hz\.oss-cn-hangzhou\.aliyuncs\.com\/open\/pptx\/\d{8}\/\d+\.pptx/g
  
  // 先进行基础格式化
  let formattedContent = pptResult.value
    .replace(/\n/g, '<br>')
    .replace(/^(\d+\.)\s/gm, '<strong>$1</strong> ')
    .replace(/^([一二三四五六七八九十]+、)/gm, '<strong>$1</strong>')
    .replace(/^(#{1,6})\s(.+)$/gm, '<h$1>$2</h$1>')
    .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
    .replace(/\*(.+?)\*/g, '<em>$1</em>')
    .replace(/^-\s(.+)$/gm, '<li>$1</li>')
    .replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>')
  
  // 根据链接状态添加相应的class
  const statusClass = linkStatus.value === 'pending' ? ' invalid' : ''
  
  // 处理OSS PPT链接
  formattedContent = formattedContent.replace(ossPptRegex, (match) => {
    return `<a href="${match}" class="ppt-link${statusClass}" target="_blank">${match}</a>`
  })
  
  // 处理被反引号包围的链接
  formattedContent = formattedContent.replace(
    /`(https:\/\/pptself-hz\.oss-cn-hangzhou\.aliyuncs\.com\/open\/pptx\/\d{8}\/\d+\.pptx)`/g,
    `<a href="$1" class="ppt-link${statusClass}" target="_blank">$1</a>`
  )
  
  return formattedContent
})

/**
 * 拦截链接点击，预校验有效性
 * @param {MouseEvent} e - 点击事件
 */
const handleLinkClick = async (e) => {
  if (e.target.tagName === 'A') {
    const url = e.target.href
    try {
      await axios.head(url, { timeout: 5000 }) // 预校验文件存在性
    } catch (error) {
      e.preventDefault() // 阻止跳转
      alert('文件暂未生成或已失效，请稍后重试～')
      console.error('[前端链接校验失败]', url, error.message)
    }
  }
}

/**
 * 轮询检查链接有效性
 * @param {string} url - 待检查的链接
 */
const startPollingForValidLink = async (url) => {
  const maxAttempts = 12 // 最多检查12次（1分钟）
  let attempts = 0
  
  const interval = setInterval(async () => {
    attempts++
    
    try {
      await axios.head(url, { timeout: 5000 })
      // 链接有效，更新状态
      linkStatus.value = 'ready'
      statusMessage.value = '文件已准备就绪'
      clearInterval(interval)
      console.log('[轮询成功] PPT文件已准备就绪:', url)
    } catch (error) {
      console.log(`[轮询检查] 第${attempts}次检查失败:`, url)
      
      if (attempts >= maxAttempts) {
        // 达到最大尝试次数，停止轮询
        clearInterval(interval)
        statusMessage.value = '文件生成超时，请稍后手动刷新'
        console.error('[轮询超时] 停止检查:', url)
      }
    }
  }, 5000) // 每5秒检查一次
}

// 生成PPT主题
const generatePPT = async () => {
  try {
    loading.value = true
    errorMessage.value = ''
    pptResult.value = ''
    downloadUrl.value = ''
    hasDownloadLink.value = false
    
    const response = await apiService.ppt.generate({
      topic: form.topic,
      subject: form.subject,
      grade: form.grade,
      slideCount: form.slideCount,
      keyPoints: form.keyPoints
    })
    
    if (response.code === 200) {
      const data = response.data
      const content = data.content
      
      // 更新PPT结果内容
      pptResult.value = content
      
      // 处理后端返回的链接状态信息
      if (data.downloadUrl) {
        hasDownloadLink.value = true
        downloadUrl.value = data.downloadUrl
        linkStatus.value = data.linkStatus || 'pending'
        statusMessage.value = data.statusMessage || ''
      } else {
        hasDownloadLink.value = false
        linkStatus.value = 'pending'
        statusMessage.value = '文件生成中，请稍后刷新'
      }
      
      // 如果状态为pending，可以启动轮询检查
      if (linkStatus.value === 'pending' && data.downloadUrl) {
        startPollingForValidLink(data.downloadUrl)
      }
      
      errorMessage.value = ''
    } else {
      errorMessage.value = response.message || '生成失败，请重试'
    }
  } catch (error) {
    console.error('生成PPT失败:', error)
    errorMessage.value = error.response?.data?.message || error.message || '网络错误，请检查连接后重试'
  } finally {
    loading.value = false
  }
}

// 重试生成
const retryGeneration = () => {
  generatePPT()
}

// 格式化内容显示
const formatContent = (content) => {
  if (!content) return ''
  
  // 将文本转换为HTML格式，保持换行和缩进
  let formattedContent = content
    .replace(/\n/g, '<br>')
    .replace(/^(\d+\.)\s/gm, '<strong>$1</strong> ')
    .replace(/^([一二三四五六七八九十]+、)/gm, '<strong>$1</strong>')
    .replace(/^(#{1,6})\s(.+)$/gm, '<h$1>$2</h$1>')
    .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
    .replace(/\*(.+?)\*/g, '<em>$1</em>')
    .replace(/^-\s(.+)$/gm, '<li>$1</li>')
    .replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>')
  
  // 识别并转换下载链接为可点击的超链接
  // 匹配 https://xxx.pptx 格式的链接
  formattedContent = formattedContent.replace(
    /(https?:\/\/[^\s]+\.pptx)/g,
    '<a href="$1" target="_blank" class="download-link">🔗 点击下载PPT文件</a>'
  )
  
  // 匹配被反引号包围的链接
  formattedContent = formattedContent.replace(
    /`(https?:\/\/[^`]+\.pptx)`/g,
    '<a href="$1" target="_blank" class="download-link">🔗 点击下载PPT文件</a>'
  )
  
  return formattedContent
}

// 新增链接解析方法
const formatContentWithLinks = (content) => {
  if (!content) return ''
  
  // 先进行基础格式化
  let formattedContent = content
    .replace(/\n/g, '<br>')
    .replace(/^(\d+\.)\s/gm, '<strong>$1</strong> ')
    .replace(/^([一二三四五六七八九十]+、)/gm, '<strong>$1</strong>')
    .replace(/^(#{1,6})\s(.+)$/gm, '<h$1>$2</h$1>')
    .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
    .replace(/\*(.+?)\*/g, '<em>$1</em>')
    .replace(/^-\s(.+)$/gm, '<li>$1</li>')
    .replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>')
  
  // 解析所有HTTP/HTTPS链接为可点击的超链接
  formattedContent = formattedContent.replace(
    /(https?:\/\/[^\s<>"']+)/g,
    '<a href="$1" target="_blank" class="ppt-link">$1</a>'
  )
  
  // 处理被反引号包围的链接
  formattedContent = formattedContent.replace(
    /`(https?:\/\/[^`\s<>"']+)`/g,
    '<a href="$1" target="_blank" class="ppt-link">$1</a>'
  )
  
  return formattedContent
}

// 复制结果
const copyResult = async () => {
  try {
    await navigator.clipboard.writeText(pptResult.value)
    alert('内容已复制到剪贴板')
  } catch (error) {
    console.error('复制失败:', error)
    alert('复制失败')
  }
}

// 下载结果
const downloadResult = () => {
  if (!pptResult.value) {
    alert('没有可下载的内容')
    return
  }
  
  const blob = new Blob([pptResult.value], { type: 'text/plain;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `PPT主题-${form.topic}.txt`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

// 下载PPT文件
const downloadPPT = () => {
  if (!downloadUrl.value) {
    alert('没有可下载的PPT文件')
    return
  }
  
  const a = document.createElement('a')
  a.href = downloadUrl.value
  a.download = `PPT-${form.topic}.pptx`
  a.target = '_blank'
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}
</script>

<style scoped>
/* 图标样式 */
.icon-document::before {
  content: '📄';
  margin-right: 8px;
}

.icon-copy::before {
  content: '📋';
  margin-right: 6px;
}

.icon-download::before {
  content: '⬇️';
  margin-right: 6px;
}

.icon-warning::before {
  content: '⚠️';
  margin-right: 8px;
}

.ppt-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.page-header {
  text-align: center;
  margin-bottom: 30px;
}

.page-header h1 {
  color: #333;
  margin-bottom: 10px;
}

.page-header p {
  color: #666;
  font-size: 1.1rem;
}

.content-wrapper {
  display: flex;
  gap: 24px;
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 20px;
  min-height: calc(100vh - 200px);
}

.left-panel {
  flex: 0 0 400px;
  min-width: 400px;
}

.right-panel {
  flex: 1;
  min-width: 600px;
}

.agent-output-card {
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  height: fit-content;
  min-height: 500px;
  position: sticky;
  top: 20px;
}

.output-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  border-bottom: 1px solid #f0f0f0;
}

.output-header h3 {
  margin: 0;
  color: #333;
  font-size: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.icon-robot::before {
  content: '🤖';
  margin-right: 8px;
}

.status-indicator {
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
}

.status-indicator.loading {
  background: #e3f2fd;
  color: #1976d2;
}

.status-indicator.success {
  background: #e8f5e8;
  color: #2e7d32;
}

.status-indicator.error {
  background: #ffebee;
  color: #c62828;
}

.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 24px;
  text-align: center;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #667eea;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.success-state {
  padding: 24px;
}

.result-content {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
  max-height: 400px;
  overflow-y: auto;
}

.content-display {
  line-height: 1.6;
  color: #333;
  font-size: 14px;
}

.action-buttons {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.error-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 24px;
  text-align: center;
}

.error-icon {
  font-size: 48px;
  color: #f44336;
  margin-bottom: 16px;
}

.initial-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 24px;
  text-align: center;
  color: #666;
}

.placeholder-icon {
  font-size: 64px;
  color: #ddd;
  margin-bottom: 20px;
}

.retry-btn {
  background: #ff6b6b;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  margin-top: 16px;
}

.retry-btn:hover {
  background: #ff5252;
}

.copy-btn, .download-btn {
  padding: 8px 16px;
  border: 1px solid #ddd;
  border-radius: 6px;
  background: white;
  cursor: pointer;
  transition: all 0.3s;
}

.copy-btn:hover, .download-btn:hover {
  background: #f5f5f5;
}

.download-btn.primary {
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
  color: white;
  border: none;
  padding: 14px 28px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 18px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(255, 107, 107, 0.4);
}

.download-btn.primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(255, 107, 107, 0.6);
  background: linear-gradient(135deg, #ee5a24 0%, #ff6b6b 100%);
}

.ppt-preview {
  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
  border: 1px solid #e9ecef;
  border-radius: 12px;
  padding: 24px;
  max-height: 600px;
  overflow-y: auto;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

.content-display {
  font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
  font-size: 15px;
  line-height: 1.8;
  color: #2c3e50;
}

.content-display h1, .content-display h2, .content-display h3 {
  color: #1a73e8;
  margin: 20px 0 12px 0;
  font-weight: 600;
}

.content-display h1 {
  font-size: 24px;
  border-bottom: 2px solid #1a73e8;
  padding-bottom: 8px;
}

.content-display h2 {
  font-size: 20px;
}

.content-display h3 {
  font-size: 18px;
}

.content-display strong {
  color: #e74c3c;
  font-weight: 600;
}

.content-display ul {
  margin: 12px 0;
  padding-left: 24px;
}

.content-display li {
  margin: 8px 0;
  position: relative;
}

.content-display li::marker {
  color: #1a73e8;
}

/* 错误提示样式 */
.error-section {
  margin-top: 24px;
}

.error-card {
  background: linear-gradient(135deg, #fff5f5 0%, #ffffff 100%);
  border: 1px solid #fed7d7;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 12px rgba(254, 215, 215, 0.3);
}

.error-header {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.error-header i {
  color: #e53e3e;
  font-size: 24px;
  margin-right: 12px;
}

.error-header h3 {
  color: #e53e3e;
  margin: 0;
  font-size: 18px;
}

.error-content p {
  color: #744210;
  margin: 0 0 16px 0;
  font-size: 15px;
}

.retry-btn {
  background: linear-gradient(135deg, #e53e3e 0%, #c53030 100%);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.retry-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(229, 62, 62, 0.3);
}

/* 下载链接样式 */
 .download-link {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 8px 16px;
   background: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);
   color: white !important;
   text-decoration: none !important;
   border-radius: 8px;
   font-weight: 500;
   font-size: 14px;
   transition: all 0.3s ease;
   box-shadow: 0 2px 8px rgba(25, 118, 210, 0.3);
   margin: 8px 0;
 }
 
 .download-link:hover {
   transform: translateY(-2px);
   box-shadow: 0 4px 16px rgba(25, 118, 210, 0.4);
   background: linear-gradient(135deg, #1565c0 0%, #0d47a1 100%);
 }
 
 .download-link:active {
   transform: translateY(0);
 }

/* PPT链接样式 */
.ppt-link {
  color: #1976d2 !important;
  text-decoration: underline !important;
  font-weight: 500;
  transition: all 0.3s ease;
  cursor: pointer;
}

.ppt-link:hover {
  color: #1565c0 !important;
  text-decoration: underline !important;
  background-color: rgba(25, 118, 210, 0.1);
  padding: 2px 4px;
  border-radius: 4px;
}

.ppt-link:active {
  color: #0d47a1 !important;
}

/* 无效链接样式 */
.ppt-link.invalid {
  color: #999 !important;
  text-decoration: line-through !important;
  pointer-events: none;
  cursor: not-allowed;
}

.ppt-link.invalid:hover {
  background-color: transparent;
  padding: 0;
}
 
 @media (max-width: 768px) {
   .content-wrapper {
     flex-direction: column;
   }
   
   .left-panel {
     flex: none;
     min-width: auto;
   }
   
   .right-panel {
     min-width: auto;
   }
 }
.form-card {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.form-card h3 {
  margin-bottom: 20px;
  color: #333;
}

.form-group {
  margin-bottom: 20px;
}

.form-group label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: #333;
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 8px;
  font-size: 14px;
  transition: border-color 0.3s;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: #4CAF50;
}

.generate-btn {
  width: 100%;
  padding: 14px;
  background: #4CAF50;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.3s;
}

.generate-btn:hover:not(:disabled) {
  background: #45a049;
}

.generate-btn:disabled {
  background: #ccc;
  cursor: not-allowed;
}

.content-display {
  font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
  font-size: 15px;
  line-height: 1.8;
  color: #2c3e50;
}

.content-display h1, .content-display h2, .content-display h3 {
  color: #1a73e8;
  margin: 20px 0 12px 0;
  font-weight: 600;
}

.content-display h1 {
  font-size: 24px;
  border-bottom: 2px solid #1a73e8;
  padding-bottom: 8px;
}

.content-display h2 {
  font-size: 20px;
}

.content-display h3 {
  font-size: 18px;
}

.content-display strong {
  color: #e74c3c;
  font-weight: 600;
}

.content-display ul {
  margin: 12px 0;
  padding-left: 24px;
}

.content-display li {
  margin: 8px 0;
  position: relative;
}

.content-display li::marker {
  color: #1a73e8;
}

/* 错误提示样式 */
.error-section {
  margin-top: 24px;
}

.error-card {
  background: linear-gradient(135deg, #fff5f5 0%, #ffffff 100%);
  border: 1px solid #fed7d7;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 12px rgba(254, 215, 215, 0.3);
}

.error-header {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.error-header i {
  color: #e53e3e;
  font-size: 24px;
  margin-right: 12px;
}

.error-header h3 {
  color: #e53e3e;
  margin: 0;
  font-size: 18px;
}

.error-content p {
  color: #744210;
  margin: 0 0 16px 0;
  font-size: 15px;
}

.retry-btn {
  background: linear-gradient(135deg, #e53e3e 0%, #c53030 100%);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.retry-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(229, 62, 62, 0.3);
}

@media (max-width: 768px) {
  .content-wrapper {
    grid-template-columns: 1fr;
  }
}
</style>